﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LeadExpress.Models;
using LeadExpress.Models.ViewPages;

namespace LeadExpress.Repository
{
    public class BannerManagementRepository : BaseManagementRepository
    {
        LeadExpressEntities entities = new LeadExpressEntities();

        public BannerManagementModel GetModel(string pageType, 
            string roleName, 
            string keywords, 
            string startDate,
            string endDate,
            string sortBy,
            string sortOrder,
            int pageSize,
            int pageIndex,
            int id)
        {
            // Update status
            if (id > 0)
            {
                var banner = GetSingle(id);
                banner.Approved = !banner.Approved;
                Update(banner);
            }

            // Set value
            BannerManagementModel model = new BannerManagementModel();
            int totalRecord = 0;
            model.ListBanner = GetAll(keywords, startDate, endDate, sortBy, sortOrder, pageSize, pageIndex, ref totalRecord);
            PaginateModel paging = new PaginateModel();

            if (totalRecord > 0)
            {
                paging.PageIndex = pageIndex;
                paging.PageSize = pageSize;
                paging.TotalRecords = totalRecord;
                paging.TotalPages = (totalRecord % pageSize == 0) ? (totalRecord / pageSize) : (totalRecord / pageSize + 1);
            }
            else
            {
                paging.PageIndex = 1;
                paging.PageSize = 10;
                paging.TotalRecords = 0;
                paging.TotalPages = 1;
            }
            model.Paging = paging;

            if (id > 0)
            {
                model.BannerInfo = GetSingle(id);
            }

            return model;
        }

        public BannerManagementModel GetModel(string pageType, string roleName, int pageSize, int pageIndex)
        {
            BannerManagementModel model = new BannerManagementModel();
            int totalRecord = 0;

            model.HeaderView = GetHeader();
            model.MenuItem = GetMenuItems(roleName, pageType);
            model.ListBanner = GetAll(string.Empty, pageSize, pageIndex, ref totalRecord);
            PaginateModel paging = new PaginateModel();

            if (totalRecord > 0)
            {
                paging.PageIndex = pageIndex;
                paging.PageSize = pageSize;
                paging.TotalRecords = totalRecord;
                paging.TotalPages = (totalRecord % pageSize == 0) ? (totalRecord / pageSize) : (totalRecord / pageSize + 1);
            }
            else
            {
                paging.PageIndex = 1;
                paging.PageSize = 10;
                paging.TotalRecords = 0;
                paging.TotalPages = 1;
            }
            model.Paging = paging;

            // Add Options
            model.ListRangeTime = GetRange();

            return model;
        }

        public BannerManagementModel GetModel(string pageType, string roleName, int id)
        {
            BannerManagementModel model = new BannerManagementModel();

            model.HeaderView = GetHeader();
            model.MenuItem = GetMenuItems(roleName, pageType);
            model.BannerInfo = GetSingle(id);

            return model;
        }

        #region #Members
        public BannerManagementModel GetModelByUser(int userId, string pageType, string roleName, string keywords, string startDate, string endDate, string sortBy, string sortOrder, int pageSize, int pageIndex, int id)
        {
            // Update status
            if (id > 0)
            {
                var banner = GetSingle(id);
                banner.Approved = !banner.Approved;
                Update(banner);
            }

            // Set value
            BannerManagementModel model = new BannerManagementModel();
            int totalRecord = 0;
            model.ListBanner = GetAllByUser(userId, keywords, startDate, endDate, sortBy, sortOrder, pageSize, pageIndex, ref totalRecord);
            PaginateModel paging = new PaginateModel();

            if (totalRecord > 0)
            {
                paging.PageIndex = pageIndex;
                paging.PageSize = pageSize;
                paging.TotalRecords = totalRecord;
                paging.TotalPages = (totalRecord % pageSize == 0) ? (totalRecord / pageSize) : (totalRecord / pageSize + 1);
            }
            else
            {
                paging.PageIndex = 1;
                paging.PageSize = 10;
                paging.TotalRecords = 0;
                paging.TotalPages = 1;
            }
            model.Paging = paging;

            if (id > 0)
            {
                model.BannerInfo = GetSingle(id);
            }

            return model;
        }
        public BannerManagementModel GetModelByUser(int userId, string pageType, string roleName, int pageSize, int pageIndex)
        {
            BannerManagementModel model = new BannerManagementModel();
            int totalRecord = 0;

            model.HeaderView = GetHeader();
            model.MenuItem = GetMenuItems(roleName, pageType);
            model.ListBanner = GetAllByUser(userId, string.Empty, pageSize, pageIndex, ref totalRecord);
            PaginateModel paging = new PaginateModel();

            if (totalRecord > 0)
            {
                paging.PageIndex = pageIndex;
                paging.PageSize = pageSize;
                paging.TotalRecords = totalRecord;
                paging.TotalPages = (totalRecord % pageSize == 0) ? (totalRecord / pageSize) : (totalRecord / pageSize + 1);
            }
            else
            {
                paging.PageIndex = 1;
                paging.PageSize = 10;
                paging.TotalRecords = 0;
                paging.TotalPages = 1;
            }
            model.Paging = paging;

            // Add Options
            model.ListRangeTime = GetRange();

            return model;
        }
        
        public BannerManagementModel GetModelByUser(int userId, string pageType, string roleName, int id)
        {
            BannerManagementModel model = new BannerManagementModel();

            model.HeaderView = GetHeader();
            model.MenuItem = GetMenuItems(roleName, pageType);
            model.BannerInfo = GetSingle(id, userId);

            return model;
        }
        #endregion

        #region #Private functions
        private List<OptionModel> GetRange()
        {
            List<OptionModel> list = new List<OptionModel>();

            OptionModel model;
            model = new OptionModel { ID = DateTime.Now.ToString("MM/dd/yyyy") + "|" + DateTime.Now.ToString("MM/dd/yyyy"), Name = "Hôm nay" };
            list.Add(model);

            model = new OptionModel { ID = DateTime.Now.AddDays(-1).ToString("MM/dd/yyyy") + "|" + DateTime.Now.AddDays(-1).ToString("MM/dd/yyyy"), Name = "Hôm qua" };
            list.Add(model);

            model = new OptionModel { ID = DateTime.Now.AddDays(-7).ToString("MM/dd/yyyy") + "|" + DateTime.Now.ToString("MM/dd/yyyy"), Name = "7 ngày trước" };
            list.Add(model);

            model = new OptionModel { ID = DateTime.Now.AddDays(-30).ToString("MM/dd/yyyy") + "|" + DateTime.Now.ToString("MM/dd/yyyy"), Name = "30 ngày trước" };
            list.Add(model);

            DateTime startDate = new DateTime();
            DateTime endDate = new DateTime();

            // before this month
            startDate = Utility.LeadTools.GetFirstDayOfMonth(DateTime.Now.Month - 1, DateTime.Now.Year);
            endDate = Utility.LeadTools.GetLastDayOfMonth(startDate);
            model = new OptionModel { ID = startDate.ToString("MM/dd/yyyy") + "|" + endDate.ToString("MM/dd/yyyy"), Name = "Tháng trước" };
            list.Add(model);

            // before 2 month
            startDate = Utility.LeadTools.GetFirstDayOfMonth(DateTime.Now.Month -2, DateTime.Now.Year);
            endDate = Utility.LeadTools.GetLastDayOfMonth(startDate.AddMonths(1));
            model = new OptionModel { ID = startDate.ToString("MM/dd/yyyy") + "|" + endDate.ToString("MM/dd/yyyy"), Name = "2 tháng trước" };
            list.Add(model);

            // Before 3 month
            startDate = Utility.LeadTools.GetFirstDayOfMonth(DateTime.Now.Month -3, DateTime.Now.Year);
            endDate = Utility.LeadTools.GetLastDayOfMonth(startDate.AddMonths(2));
            model = new OptionModel { ID = startDate.ToString("MM/dd/yyyy") + "|" + endDate.ToString("MM/dd/yyyy"), Name = "3 tháng trước" };
            list.Add(model);

            // This month
            startDate = Utility.LeadTools.GetFirstDayOfMonth(DateTime.Now.Month, DateTime.Now.Year);
            endDate = Utility.LeadTools.GetLastDayOfMonth(startDate);
            model = new OptionModel { ID = startDate.ToString("MM/dd/yyyy") + "|" + endDate.ToString("MM/dd/yyyy"), Name = "Tháng này" };
            list.Add(model);

            // All time
            model = new OptionModel { ID = "-1", Name = "Tất cả" };
            list.Add(model);

            return list;
        }
        
        private List<BannerModel> GetAllByUser(int userId, string keywords, string startDate, string endDate, string sortBy, string sortOrder, int pageSize, int pageIndex, ref int total)
        {
            List<BannerModel> list = new List<BannerModel>();
            List<Banner> listTemp = new List<Banner>();
            var banners = (from c in entities.Banners
                           where c.CreatedByUserID == userId
                           select c);
            
            // Check conditions
            if (!string.IsNullOrEmpty(keywords))
                banners = banners.Where(c => c.Title.Contains(keywords));

            DateTime isStartDate;
            if (!string.IsNullOrEmpty(startDate) && DateTime.TryParse(startDate, out isStartDate))
            {
                DateTime sDate = Convert.ToDateTime(startDate);
                banners = banners.Where(c => c.DateCreated >= sDate);
            }
            DateTime isEndDate;
            if (!string.IsNullOrEmpty(endDate) && DateTime.TryParse(endDate, out isEndDate))
            {
                DateTime eDate = Convert.ToDateTime(endDate);
                banners = banners.Where(c => c.DateCreated <= eDate);
            }
            
            // Get total count
            try
            {
                if (banners != null && banners.Count() > 0)
                {
                    total = banners.Count();

                    // Sort by Column|Order
                    sortOrder = sortOrder.ToUpper();
                    sortBy = sortBy.ToUpper();
                    switch (sortBy)
                    {
                        case "TITLE":
                            {
                                if(sortOrder == "ASC")
                                    listTemp = banners.OrderBy(c => c.Title).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                else
                                    listTemp = banners.OrderByDescending(c => c.Title).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                break;
                            }
                        case "SHORTDESC":
                            {
                                if (sortOrder == "ASC")
                                    listTemp = banners.OrderBy(c => c.ShortDesc).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                else
                                    listTemp = banners.OrderByDescending(c => c.ShortDesc).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                break;
                            }
                        case "DATECREATED":
                            {
                                if (sortOrder == "ASC")
                                    listTemp = banners.OrderBy(c => c.DateCreated).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                else
                                    listTemp = banners.OrderByDescending(c => c.DateCreated).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                break;
                            }
                        case "APPROVED":
                            {
                                if (sortOrder == "ASC")
                                    listTemp = banners.OrderBy(c => c.Approved).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                else
                                    listTemp = banners.OrderByDescending(c => c.Approved).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                break;
                            }
                        default:
                            {
                                if(sortOrder == "ASC")
                                    listTemp = banners.OrderByDescending(c => c.DateCreated).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                else
                                    listTemp = banners.OrderByDescending(c => c.DateCreated).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                break;
                            }
                    }
                }
            }
            catch (Exception ex)
            {
                Helpers.ErrorHandle.AddError(ex.Message);
            }

            // Add list
            foreach (var item in listTemp)
            {
                BannerModel model = new BannerModel();
                model.ID = item.ID;
                model.Title = item.Title;
                model.ShortDesc = item.ShortDesc;
                model.LongDesc = item.LongDesc;
                model.ImageURL = item.ImageURL;
                model.FlashURL = item.FlashURL;
                model.HTML = item.HTML;
                model.CreationDate = Convert.ToDateTime(item.DateCreated).ToString("dd-MM-yyyy hh:mm tt");
                model.Approved = item.Approved;
                model.Active = item.Active;

                list.Add(model);
            }

            return list;
        }


        private List<BannerModel> GetAll(string keywords, string startDate, string endDate, string sortBy, string sortOrder, int pageSize, int pageIndex, ref int total)
        {
            List<BannerModel> list = new List<BannerModel>();
            List<Banner> listTemp = new List<Banner>();
            var banners = (from c in entities.Banners
                           select c);
            
            // Check conditions
            if (!string.IsNullOrEmpty(keywords))
                banners = banners.Where(c => c.Title.Contains(keywords));

            DateTime isStartDate;
            if (!string.IsNullOrEmpty(startDate) && DateTime.TryParse(startDate, out isStartDate))
            {
                DateTime sDate = Convert.ToDateTime(startDate);
                banners = banners.Where(c => c.DateCreated >= sDate);
            }
            DateTime isEndDate;
            if (!string.IsNullOrEmpty(endDate) && DateTime.TryParse(endDate, out isEndDate))
            {
                DateTime eDate = Convert.ToDateTime(endDate);
                banners = banners.Where(c => c.DateCreated <= eDate);
            }
            
            // Get total count
            try
            {
                if (banners != null && banners.Count() > 0)
                {
                    total = banners.Count();

                    // Sort by Column|Order
                    sortOrder = sortOrder.ToUpper();
                    sortBy = sortBy.ToUpper();
                    switch (sortBy)
                    {
                        case "TITLE":
                            {
                                if(sortOrder == "ASC")
                                    listTemp = banners.OrderBy(c => c.Title).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                else
                                    listTemp = banners.OrderByDescending(c => c.Title).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                break;
                            }
                        case "SHORTDESC":
                            {
                                if (sortOrder == "ASC")
                                    listTemp = banners.OrderBy(c => c.ShortDesc).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                else
                                    listTemp = banners.OrderByDescending(c => c.ShortDesc).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                break;
                            }
                        case "DATECREATED":
                            {
                                if (sortOrder == "ASC")
                                    listTemp = banners.OrderBy(c => c.DateCreated).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                else
                                    listTemp = banners.OrderByDescending(c => c.DateCreated).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                break;
                            }
                        case "APPROVED":
                            {
                                if (sortOrder == "ASC")
                                    listTemp = banners.OrderBy(c => c.Approved).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                else
                                    listTemp = banners.OrderByDescending(c => c.Approved).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                break;
                            }
                        default:
                            {
                                if(sortOrder == "ASC")
                                    listTemp = banners.OrderByDescending(c => c.DateCreated).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                else
                                    listTemp = banners.OrderByDescending(c => c.DateCreated).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                                break;
                            }
                    }
                }
            }
            catch (Exception ex)
            {
                Helpers.ErrorHandle.AddError(ex.Message);
            }

            // Add list
            foreach (var item in listTemp)
            {
                BannerModel model = new BannerModel();
                model.ID = item.ID;
                model.Title = item.Title;
                model.ShortDesc = item.ShortDesc;
                model.LongDesc = item.LongDesc;
                model.ImageURL = item.ImageURL;
                model.FlashURL = item.FlashURL;
                model.HTML = item.HTML;
                model.CreationDate = Convert.ToDateTime(item.DateCreated).ToString("dd-MM-yyyy hh:mm tt");
                model.Approved = item.Approved;
                model.Active = item.Active;

                list.Add(model);
            }

            return list;
        }

        private List<BannerModel> GetAllByUser(int userId, string keywords, int pageSize, int pageIndex, ref int total)
        {
            List<BannerModel> list = new List<BannerModel>();

            var banners = (from c in entities.Banners
                           where c.CreatedByUserID == userId
                           select c);

            // Check conditions
            if (!string.IsNullOrEmpty(keywords))
                banners = banners.Where(c => c.Title.Contains(keywords));

            // Get total count
            total = banners.Count();

            var items = banners.OrderByDescending(c => c.DateCreated).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

            foreach (var item in items)
            {
                BannerModel model = new BannerModel();
                model.ID = item.ID;
                model.Title = item.Title;
                model.ShortDesc = item.ShortDesc;
                model.LongDesc = item.LongDesc;
                model.ImageURL = item.ImageURL;
                model.FlashURL = item.FlashURL;
                model.HTML = item.HTML;
                model.CreationDate = Convert.ToDateTime(item.DateCreated).ToString("dd-MM-yyyy hh:mm tt");
                model.Approved = item.Approved;
                model.Active = item.Active;

                list.Add(model);
            }

            return list;
        }


        private List<BannerModel> GetAll(string keywords, int pageSize, int pageIndex, ref int total)
        {
            List<BannerModel> list = new List<BannerModel>();

            var banners = (from c in entities.Banners
                           select c);

            // Check conditions
            if (!string.IsNullOrEmpty(keywords))
                banners = banners.Where(c => c.Title.Contains(keywords));
            
            // Get total count
            total = banners.Count();

            var items = banners.OrderByDescending(c => c.DateCreated).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

            foreach (var item in items)
            {
                BannerModel model = new BannerModel();
                model.ID = item.ID;
                model.Title = item.Title;
                model.ShortDesc = item.ShortDesc;
                model.LongDesc = item.LongDesc;
                model.ImageURL = item.ImageURL;
                model.FlashURL = item.FlashURL;
                model.HTML = item.HTML;
                model.CreationDate = Convert.ToDateTime(item.DateCreated).ToString("dd-MM-yyyy hh:mm tt");
                model.Approved = item.Approved;
                model.Active = item.Active;

                list.Add(model);
            }

            return list;
        }

        private bool IsExist(string[] arr, int? id)
        {
            bool isExist=false;

            for(int i=0;i<arr.Length;i++)
            {
                if(int.Parse(arr[i]) == id)
                {
                    isExist=true;
                    break;
                }
            }

            return isExist;
        }
        #endregion

        #region Reference function
        public Banner GetSingle(int id, int userId)
        {
            return (from _object in entities.Banners 
                    where _object.ID == id && _object.CreatedByUserID == userId
                    select _object).FirstOrDefault();
        }

        public Banner GetSingle(int id)
        {
            return (from _object in entities.Banners where _object.ID == id select _object).FirstOrDefault();
        }
        
        public void Create([Bind(Exclude = "ID, DateCreated")] Banner _object)
        {
            _object.DateCreated = System.DateTime.Now;
            entities.AddToBanners(_object);
            entities.SaveChanges();
        }

        public void Delete(int id)
        {
            var _object = (from _list in entities.Banners where _list.ID == id select _list).First();
            entities.DeleteObject(_object);
            entities.SaveChanges();
        }

        public void Update(Banner _object)
        {
            _object.DateCreated = System.DateTime.Now;
            entities.SaveChanges();
        }

        public void Save([Bind(Exclude = "ID")] Banner _object)
        {
            _object.EntityKey = (from Banner ac in entities.Banners where ac.ID == _object.ID select ac).FirstOrDefault().EntityKey;
            _object.DateCreated = System.DateTime.Now;
            entities.SaveChanges();
        }
        #endregion
    }
}
